mod divi_zipper;
mod divi_join;
mod acbl;
mod biz_fee;
mod trls;
mod indi_clie;
use acbl::AcblBack;
use biz_fee::BizFeeBack;
use chrono::NaiveDate;
pub use divi_join::*;
use divi_zipper::DiviZipper;
use indi_clie::IndiClieAcbl;
use redis::Commands;
use strum::IntoEnumIterator;
use trls::TrlsBack;
use tracing::{info, instrument};

use crate::{base::{delete_all_tmp_table, get_ch_pool, get_etl_redis_cli, get_imp_config, get_ui_redis_cli, update_tmst, DiviType, ImportType, SourceType}, big_table::{calc_proc_with_divi_type, BigTable}};

pub async fn divi_back()->anyhow::Result<()>{
    let rcil=get_etl_redis_cli();
    let mut rcon=rcil.get_connection()?;
    let res:bool=rcon.set_nx("divi_backing", 1_u8)?;
    if res==false{
        log::warn!("认定关系追溯正在运行中，本次运行终止");
        return Ok(());
    }
    let rcil2=get_ui_redis_cli();
    let mut rcon2=rcil2.get_connection()?;
    let _:()=rcon.expire("divi_backing", 60*60*4)?;
    let _:()=rcon2.set_ex("import_run", 1, 60*60*4)?;
    let mut is_exec:bool=false;
    for st in DiviType::iter() {
        let res=divi_back_by_type(st).await;
        match res {
            Ok(is_ok) => if is_ok {is_exec=is_ok},
            Err(e) => {
                log::error!("{}认定关系追溯失败:{}", st, e);
                let _:()=rcon.del("divi_backing")?;
                return Err(e);
            },
        }
    }
    let _: i64 = rcon.del("divi_backing")?;
    let _: i64 = rcon2.del("import_run")?;
    if is_exec{
        update_tmst().await?;
        delete_all_tmp_table().await?;
    }
    Ok(())
}
#[instrument]
async fn divi_back_by_type(divi_type:DiviType)->anyhow::Result<bool>{
    let back_date=DiviZipper::new(divi_type).zip_divi().await?;
    if back_date.is_none(){
        return Ok(false);
    }
    let sdate=back_date.unwrap();
    let sql = "select max(DTID) from DFKB_COMP_CLIE_INDEX";
    let mut client = get_ch_pool().get_handle().await?;
    let b = client.query(&sql).fetch_all().await?;
    let edate:NaiveDate=b.rows().next().unwrap().get(0)?;
    info!("数据源{divi_type}开始认定关系追溯");
    for st in SourceType::iter() {
        let imp_conf=get_imp_config(st);
        for t in imp_conf.tables.iter(){
            if !t.divi_fact_convs.iter().any(|d|d.divi_type==divi_type) {
                continue
            }
            if t.import_type==ImportType::InsertAndUpdate && t.acbl_procs.is_some() {
                let ap=t.acbl_procs.as_ref().unwrap();
                if ap.acbl_table_name=="T_INDI_CLIE_ACBL" {
                    IndiClieAcbl::new(&sdate).run().await?;
                }
                AcblBack::new(divi_type, &sdate, t).run().await?;
            }else if t.import_type==ImportType::MonthTrls || t.import_type==ImportType::DayTrls {
                if t.file_name=="CM_BIZ_FEE_SUM_M"  {
                    BizFeeBack::new().run().await?;
                }else{
                    TrlsBack::new(divi_type, t).run().await?;
                }
            }
            info!("开始{}认定关系追溯",t.file_name);
            let bt=BigTable::new(st,&t.file_name);
            bt.back_clear(&sdate, &edate).await?;
            bt.back_build(&sdate, &edate).await?;
            info!("{}认定关系追溯完成",t.file_name);
        }
    }
    calc_proc_with_divi_type(&sdate, &edate,&divi_type,true).await?;
    info!("数据源{divi_type}认定关系追溯完成");
    Ok(true)
}